using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.ComponentModel.Design.Serialization;
using System.Reflection;
using System.ComponentModel.Design;
using EnvDTE;

namespace XnaDesignerGenerator
{
    [DesignerSerializer(typeof(XnaGameServiceGenerator), typeof(CodeDomSerializer))]
    [Designer(typeof(XnaGameComponentDesigner), typeof(IDesigner))]
    [ToolboxItemFilter("Microsoft.Xna.Framework", ToolboxItemFilterType.Require)]
    public class XnaGameService : Component, XnaComponent
    {
        private object component;

        [Browsable(true)]
        [TypeConverter(typeof(ExpandableObjectConverter))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public object Component
        {
            get { return component; }
            set
            {
                component = value;
                if (parent != null)
                {
                    if (((GameManager)parent).Game != null)
                    {
                        try
                        {
                            ((GameManager)parent).Game.Services.AddService(component.GetType(), component);
                            if(component is Microsoft.Xna.Framework.GameComponent)
                                ((GameManager)parent).Game.Components.Add((Microsoft.Xna.Framework.GameComponent)component);
                        }
                        catch { }
                    }
                }
                if (serviceClass == null)
                    ServiceClass = value.GetType();
                if (project == null)
                {
                    Project projectExistent = (Project)TypeDescriptor.GetConverter(typeof(Project)).ConvertFrom(serviceClass.Namespace);
                    if (projectExistent != null)
                    {
                        project = projectExistent;
                    }
                }
            }
        }

        private Type serviceClass;

        [Browsable(true)]
        [TypeConverter(typeof(ObjectServiceListConverter))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Type ServiceClass
        {
            get { return serviceClass; }
            set
            {
                serviceClass = value;
            }
        }

        
        private Assembly assembly;

        [Category("Xna")]
        [TypeConverter(typeof(AssemblyListConverter))]
        public Assembly Assembly
        {
            get
            {
                if (assembly == null && (serviceInterface != null || component != null))
                {
                    if (serviceInterface != null)
                        assembly = serviceInterface.Assembly;
                    else
                        assembly = component.GetType().Assembly;
                }
                return assembly;
            }
            set { assembly = value; }
        }


        private Type serviceInterface;

        [Browsable(true)]
        [Category("Xna")]
        [TypeConverter(typeof(InterfaceListConverter))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public Type ServiceInterface
        {
            get { return serviceInterface; }
            set
            {
                serviceInterface = value;
                assembly = value.Assembly;
            }
        }

        private Component parent;

        [Category("Xna")]
        [Browsable(false)]
        public Component Parent
        {
            get { return parent; }
            set
            {
                parent = value;
                if (component != null)
                {
                    try
                    {
                        ((GameManager)value).Game.Services.AddService(component.GetType(), component);
                    }
                    catch { }
                }
            }
        }

        private EnvDTE.Project project;

        [DesignOnly(true)]
        [Category("Xna")]
        [TypeConverter(typeof(ProjectTypeConverter))]
        public EnvDTE.Project Project
        {
            get { return project; }
            set { project = value; }
        }
    }
}
